package com.sj.purchase.modules.cost.web;

import com.sj.purchase.manager.SkuInfoManager;
import com.sj.purchase.modules.cost.repository.order.InOrderItemRepository;
import com.sj.purchase.common.Result;
import com.sj.purchase.modules.cost.repository.order.OutOrderItemRepository;
import com.sj.purchase.modules.cost.repository.stock.SkuStockRepository;
import com.sj.purchase.manager.SkuInfo;
import com.sj.purchase.util.ExcelDownloadUtil;
import com.sj.purchase.modules.cost.views.stock.StockCheckVO;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.stream.Collectors;

import static com.sj.purchase.common.ResultGenerator.ok;

/**
 * 库存校验
 * Created by yangrd on 2017/7/21.
 */
@Deprecated
@RestController
@RequestMapping("/api/stock/check")
public class StockCheckController {

    private static final List<StockCheckVO> CONTENT_EMPTY = new ArrayList<>(1);

    @Autowired
    private SkuStockRepository skuStockRepository;

    @Autowired
    private SkuInfoManager skuInfoManager;

    @Autowired
    private InOrderItemRepository inOrderItemRepository;

    @Autowired
    private OutOrderItemRepository outOrderItemRepository;

    @GetMapping
    public Result<Page<StockCheckVO>> getSkuLike(Date day, @RequestParam(defaultValue = "") String sku, Pageable pageable) {
        //明天期初库存
        Pair<List<StockCheckVO>, Long> pair = getStockCheckAndTotal(day, sku, pageable);
        return ok(new PageImpl<>(pair.getLeft(), pageable, pair.getRight()));
    }

    @GetMapping("excel")
    public void exportStockCheckExcel(Date day, @RequestParam(defaultValue = "") String sku) {
        ExcelDownloadUtil.easyPoi("库存校验", StockCheckVO.class, getStockCheckAndTotal(day, sku, null).getLeft());
    }

    //用new PageImpl 会导致excel导出出错
    private Pair<List<StockCheckVO>, Long> getStockCheckAndTotal(Date day, @RequestParam(defaultValue = "") String sku, Pageable pageable) {
        //TODO 算法需要修改
        //今天的期末  = 今天的起初 + (入庫-出庫)
        Page<String> skuNoPage = skuStockRepository.findBaseStockSku(sku + "%", day, pageable);
        List<String> skuNoList = skuNoPage.getContent();
        List<Object[]> todayBeginStock = skuStockRepository.findBeginStock(day, skuNoList);
        if (skuNoList.isEmpty()) {
            return Pair.of(CONTENT_EMPTY, 0L);
        }
        //某天 入库-出库的库存信息
        Map<String, Long> orderStockMap = this.getOrderStockMap(day, skuNoList);
        Map<String, Long> beginStockSkuNumMap = todayBeginStock.stream().collect(Collectors.toMap(skuAndNum -> (String) skuAndNum[0], skuAndNum -> (Long) skuAndNum[1]));
        List<StockCheckVO> stockCheckVOList = skuNoList.stream().map(skuNo -> {
            Long num = beginStockSkuNumMap.getOrDefault(skuNo, 0L);
            num += orderStockMap.getOrDefault(skuNo, 0L);
            SkuInfo skuInfo = skuInfoManager.getSkuInfo(skuNo);
            return new StockCheckVO().setDarwin(skuInfo.getDarwin()).setSpuNo(skuInfo.getSpucode()).setSpuName(skuInfo.getSpuname()).setSkuNo(skuNo).setSkuName(skuInfo.getSkuname()).setDay(day).setOutStockNum(num);
        }).collect(Collectors.toList());
        // 明天的起初
        Map<String, Long> endDayBeginStockMap = skuStockRepository.findBeginStock(DateUtils.addDays(day, 1), skuNoList).stream().collect(Collectors.toMap(skuAndNum -> (String) skuAndNum[0], skuAndNum -> (Long) skuAndNum[1]));
        //差异 = 今天的期末 - 明天的起初
        stockCheckVOList.stream().forEach(stockCheckVO -> {
            String skuNo = stockCheckVO.getSkuNo();
            Long num = endDayBeginStockMap.getOrDefault(skuNo, 0L);
            stockCheckVO.setNextDayBeginStockNum(num).setStockDiff(stockCheckVO.getOutStockNum() - num);
        });
        return Pair.of(stockCheckVOList, skuNoPage.getTotalElements());
    }

    // 入库sku数量-出库sku数量
    private Map<String, Long> getOrderStockMap(Date day, List<String> skuNos) {
        List<Object[]> inOrderItemSkuAndNumList = inOrderItemRepository.listSkuNumGroupBySkuNo(day, skuNos);
        List<Object[]> outOrderItemSkuAndNumList = outOrderItemRepository.listSkuNumGroupBySkuNo(day, skuNos);
        Map<String, Long> inOrderItemSkuAndNumMap = inOrderItemSkuAndNumList.stream().collect(Collectors.toMap(skuAndNum -> (String) skuAndNum[0], skuAndNum -> (Long) skuAndNum[1]));
        Map<String, Long> outOrderItemSkuAndNumMap = outOrderItemSkuAndNumList.stream().collect(Collectors.toMap(skuAndNum -> (String) skuAndNum[0], skuAndNum -> (Long) skuAndNum[1]));
        outOrderItemSkuAndNumMap.forEach((skuNo, num) -> {
            if (inOrderItemSkuAndNumMap.containsKey(skuNo)) {
                Long inNum = inOrderItemSkuAndNumMap.get(skuNo);
                inOrderItemSkuAndNumMap.put(skuNo, inNum - num);
            } else {
                inOrderItemSkuAndNumMap.put(skuNo, -1 * num);
            }
        });
        return inOrderItemSkuAndNumMap;
    }
}
